package com.zlcx.tz.live.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.green.model.v20170825.ImageSyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.zlcx.tz.live.utils.MD5Util;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.validation.constraints.NotNull;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * <p>阿里内容检测API</p>
 * <PRE>
 * <BR>    修改记录
 * <BR>-----------------------------------------------
 * <BR>    修改日期         修改人          修改内容
 * </PRE>
 *
 * @author zl
 * @version 1.0
 * @date Created in 2019/11/5 13:53
 * @copyright: Copyright (c) founders
 */

@Slf4j
@Service
public class AliContentCheckService {


    @Value("${accessKeyId}")
    private String accessKeyId;

    @Value("${accessKeySecret}")
    private String accessKeySecret;

    @Value("${regionId}")
    private String regionId;


    public List<ImageCheckResult> imagesSyncCheck(Set<String> imageUrls) throws ClientException, UnsupportedEncodingException {

        if(CollectionUtils.isEmpty(imageUrls)){
            return null;
        }

        IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultProfile.addEndpoint(getEndPointName(), regionId, "Green", getDomain());
        IAcsClient client = new DefaultAcsClient(profile);

        ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
        imageSyncScanRequest.setAcceptFormat(FormatType.JSON);
        imageSyncScanRequest.setMethod(com.aliyuncs.http.MethodType.POST);
        imageSyncScanRequest.setEncoding("utf-8");
        imageSyncScanRequest.setRegionId(regionId);

        List<Map<String, Object>> tasks = new ArrayList<Map<String, Object>>();
        for(String url:imageUrls){
            Map<String, Object> task = new LinkedHashMap<String, Object>();
            task.put("dataId", MD5Util.MD5Normal(url));
            task.put("url", url);
            task.put("time", new Date());
            tasks.add(task);
        }

        JSONObject data = new JSONObject();
        data.put("scenes", Arrays.asList("porn"));
        data.put("tasks", tasks);

        String content = data.toJSONString();
        log.info("实时鉴黄参数：{}", content);
        imageSyncScanRequest.setHttpContent(content.getBytes("UTF-8"), "UTF-8", FormatType.JSON);
        imageSyncScanRequest.setConnectTimeout(3000);
        imageSyncScanRequest.setReadTimeout(6000);

        HttpResponse httpResponse = client.doAction(imageSyncScanRequest);
        int status = httpResponse.getStatus();
        String respContent = new String(httpResponse.getHttpContent(), "UTF-8");
        log.info("实时鉴黄响应：status={},respContent={}", status, respContent);

        if (!httpResponse.isSuccess()) {
            log.error("实时鉴黄响应状态码不正确：status={},respContent={}", status, respContent);
            return null;
        }

        JSONObject scrResponse = JSON.parseObject(respContent);
        if (200 != scrResponse.getInteger("code")) {
            log.error("实时鉴黄失败：status={},respContent={}", status, respContent);
            return null;
        }

        List<ImageCheckResult> checkResults = Lists.newArrayList();

        JSONArray taskResults = scrResponse.getJSONArray("data");
        for (Object taskResult : taskResults) {

            ImageCheckResult imageCheckResult = new ImageCheckResult();
            imageCheckResult.setImageUrl(((JSONObject) taskResult).getString("url"));
            imageCheckResult.setCode(((JSONObject) taskResult).getInteger("code"));
            imageCheckResult.setMsg(((JSONObject) taskResult).getString("msg"));

            if (200 != ((JSONObject) taskResult).getInteger("code")) {
                log.error("实时鉴黄存在检测失败任务：dataId={},code={},msg={}", ((JSONObject) taskResult).getString("dataId")
                        ,((JSONObject) taskResult).getInteger("code"), ((JSONObject) taskResult).getString("msg"));

                checkResults.add(imageCheckResult);
                continue;
            }

            JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
            JSONObject sceneMaxObj = null;
            for(int i=0;i<sceneResults.size();i++){
                JSONObject sceneObj = sceneResults.getJSONObject(i);
                if(sceneMaxObj == null || sceneMaxObj.getDoubleValue("rate") < sceneObj.getDoubleValue("rate")){
                    sceneMaxObj = sceneObj;
                }

            }

            imageCheckResult.setScene(sceneMaxObj.getString("scene"));
            imageCheckResult.setLabel(sceneMaxObj.getString("label"));
            imageCheckResult.setSuggestion(sceneMaxObj.getString("suggestion"));
            imageCheckResult.setRate(sceneMaxObj.getDoubleValue("rate"));

            checkResults.add(imageCheckResult);

        }

        return checkResults;

    }

    public  ImageCheckResult checkOneImage(@NotEmpty String imageUrl) throws UnsupportedEncodingException, ClientException {

        List<ImageCheckResult>  results = imagesSyncCheck(Sets.newHashSet(imageUrl));
        if(!CollectionUtils.isEmpty(results)){
            return results.get(0);
        }
        return null;
    }

    public boolean imageIsNomal(@NotNull ImageCheckResult checkResult){

//        if("normal".equals(checkResult.getLabel())
//                && "pass".equals(checkResult.getSuggestion())
//                && 30 < checkResult.getRate()){
//            return true;
//        }

        if( "normal".equals(checkResult.getLabel()) || checkResult.getRate() < 90 ){
            return true;
        }

        return false;
    }

    public boolean imageIsPorn(@NotNull ImageCheckResult checkResult){

        if(!"normal".equals(checkResult.getLabel())
                && "block".equals(checkResult.getSuggestion())
                && 98 < checkResult.getRate()){
            return true;
        }

        return false;
    }


    private String getDomain() {
        if ("cn-shanghai".equals(regionId)) {
            return "green.cn-shanghai.aliyuncs.com";
        }

        if ("cn-hangzhou".equals(regionId)) {
            return "green.cn-hangzhou.aliyuncs.com";
        }

        if ("local".equals(regionId)) {
            return "api.green.alibaba.com";
        }

        return "green.cn-shanghai.aliyuncs.com";
    }

    private String getEndPointName() {
        return regionId;
    }


    public String getLabelMsg(String label) {

        if (StringUtils.isBlank(label)) {
            return label;
        }

        switch (label) {
            case "normal":
                return "正常图片，无色情";
            case "sexy":
                return "性感图片";
            case "vulgar":
                return "低俗图片";
            case "porn":
                return "色情图片";
            default:
                return label;
        }

    }

    public String getSuggestionMsg(String suggestion) {

        if (StringUtils.isBlank(suggestion)) {
            return suggestion;
        }

        switch (suggestion) {
            case "pass":
                return "无需处理";
            case "review":
                return "需要人工审核";
            case "block":
                return "图片违规";
            default:
                return suggestion;
        }
    }

    @Data
    public class ImageCheckResult{

        private String imageUrl;
        private Integer code;
        private String msg;
        private String scene;
        private String label;
        private String suggestion;
        private Double rate;

    }



}
